package com.fc.persistence.core;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fc.persistence.dao.DAOTemplate;
import com.fc.persistence.exception.IDBException;

@Transactional
public class TranscationImpl implements ITranscation {
	private SessionFactory sessionFactory;

	private Session currentSession() {
		if (!sessionFactory.getCurrentSession().isOpen()) {
			try {
				sessionFactory.openSession();
			} catch (Exception e) {
				throw new IDBException(e.getMessage(), e);
			}
		}
		return sessionFactory.getCurrentSession();
	}

	@Override
	public void save(DAOTemplate obj) {
		currentSession().saveOrUpdate(obj);
		//TODO
		// currentSession().persist(obj);
	}

	@Override
	public void delete(DAOTemplate obj) {
		currentSession().delete(obj);
	}

	@Override
	public void update(DAOTemplate obj) {
		currentSession().update(obj);
	}

	@Override
	public DAOTemplate getById(Long id, @SuppressWarnings("rawtypes") Class clazz) {
		String sql = "from " + clazz.getSimpleName() + " where id = " + id;
		Query query = null;
		try {
			query = currentSession().createQuery(sql);
			query.setCacheable(true);
		} catch (Exception e) {
			throw new IDBException(e.getMessage(), e);
		}
		@SuppressWarnings("unchecked")
		List<DAOTemplate> results = query.list();
		if (results == null || results.size() == 0) {
			return null;
		}
		return results.get(0);
	}

	@Override
	public List<DAOTemplate> getAll(String tableName) {
		String sql = "from " + tableName;
		Query query = null;
		try {
			query = currentSession().createQuery(sql);
			query.setCacheable(true);
		} catch (Exception e) {
			throw new IDBException(e.getMessage(), e);
		}
		@SuppressWarnings("unchecked")
		List<DAOTemplate> results = query.list();
		return results;
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<DAOTemplate> getBySQL(String sql) {
		Query query = null;
		try {
			query = currentSession().createQuery(sql);
			query.setCacheable(true);
		} catch (Exception e) {
			throw new IDBException(e.getMessage(), e);
		}
		@SuppressWarnings("unchecked")
		List<DAOTemplate> results = query.list();
		return results;
	}

	@Override
	public List<DAOTemplate> getBySQL(String sql, int startIndex, int limit) {
		Query query = null;
		try {
			query = currentSession().createQuery(sql);
			query.setCacheable(true);
		} catch (Exception e) {
			throw new IDBException(e.getMessage(), e);
		}
		query.setFirstResult(startIndex);
		query.setMaxResults(limit);
		@SuppressWarnings("unchecked")
		List<DAOTemplate> results = query.list();
		return results;
	}

	@Override
	public void deleteBySQL(String sql) {
		Query query = null;
		try {
			query = currentSession().createQuery(sql);
			query.setCacheable(true);
		} catch (Exception e) {
			throw new IDBException(e.getMessage(), e);
		}
		query.executeUpdate();
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
}
